import * as DataServices from '../../services/Editor/data';
import * as WidgetServices from '../../services/Editor/widgets';
import * as TimelineServices from '../../services/Editor/timelines';
import persistHelper from '../../utils/persistHelper';

const dataHelper = {
    filterPageData(data) {
        const obj = {};
        for (let i = 0; i < data.length; i++) {
            if (!obj[data[i].page_id]) obj[data[i].page_id] = [];
            obj[data[i].page_id].push(data[i]);
        }
        return obj;
    },
    filterWidgetData(data) {
        const obj = {};
        for (let i = 0; i < data.length; i++) {
            if (!obj[data[i].widget_id]) obj[data[i].widget_id] = [];
            obj[data[i].widget_id].push(data[i]);
        }
        return obj;
    },
    parseWidgetsFromServer(objWidgets) {
        let pWidgets = [];
        for (const pageId in objWidgets) {
            let widgets = objWidgets[pageId];
            if (widgets instanceof Array) {
                widgets = widgets.map((w) => {
                    w.page_id = pageId;
                    return w;
                });
                pWidgets = pWidgets.concat(widgets);
            }
        }
        return pWidgets;
    },
    parseTimelinesFromServer(objTimelines, objWidgets) {
        let pTimelines = [];
        const objWidgetsIds = {};
        objWidgets.forEach((t) => {
            objWidgetsIds[t.widget_id] = t;
        });
        for (const widgetId in objTimelines) {
            let timelines = objTimelines[widgetId];
            if (timelines instanceof Array) {
                timelines = timelines.map((w) => {
                    w.widget_id = widgetId;
                    w.page_id = objWidgetsIds[w.widget_id].page_id;
                    return w;
                });
                pTimelines = timelines.concat(timelines);
            }
        }
        return pTimelines;
    },
    parsePagesFromServer(pages) {
        return pages.map((p, index) => {
            p.fetched = true;
            p.color = index;
            return p;
        });
    },
};

export default {
    namespace: 'data',
    state: {
        outOfDate: true,
        serverTimestamp: 0,
        data: {},
    },
    reducers: {
        save(prevState, { payload: newState }) {
            return { ...prevState, ...newState };
        },
    },
    effects: {
        *deleteWidgets({ payload: widgets }, { call }) {
            for (let i = 0; i < widgets.length; i++) {
                const widgetId = widgets[i].widget_id;
                const pageId = widgets[i].page_id;
                yield call(WidgetServices.remove, pageId, widgetId);
            }
        },
        *deleteTimelines({ payload: timelines }, { call }) {
            for (let i = 0; i < timelines.length; i++) {
                const widgetId = timelines[i].widget_id;
                const timelineId = timelines[i].timeline_id;
                yield call(TimelineServices.remove, widgetId, timelineId);
            }
        },
        *saveEditorData({ payload }, { call, put, select }) {
            const state = yield select(s => s);
            const delWidgets = state.widgets.filter(w => w.delFlag);
            const noDelWidgets = state.widgets.filter(w => !w.delFlag);
            const delWidgetsIds = delWidgets.filter(w => w.widget_id);
            const noDelTimelines = state.timelines.filter(w => !w.delFlag && delWidgetsIds.indexOf(w.widget_id) === -1);
            const delTimelines = state.timelines.filter(w => w.delFlag || delWidgetsIds.indexOf(w.widget_id) !== -1);
            const { data } = yield call(DataServices.save, {
                pages: state.pages,
                pageTimelines: dataHelper.filterPageData(state.pageTimelines),
                pageJump: state.pageJump,
                widgets: dataHelper.filterPageData(noDelWidgets),
                timelines: dataHelper.filterWidgetData(noDelTimelines),
                delWidgets,
                delTimelines,
            });
            // 后端暂未实现 删除组件 ，暂且前端将删除的组件调用之前的删除接口实现
            yield put({
                type: 'deleteTimelines',
                payload: delTimelines,
            });
            yield put({
                type: 'deleteWidgets',
                payload: delWidgets,
            });

            // 调整保存后的数据
            yield put({
                type: 'save',
                payload: {
                    saved: true,
                    serverTimestamp: data.timestamp,
                },
            });
            yield put({
                type: 'widgets/resetWidgets',
                payload: noDelWidgets,
            });
            yield put({
                type: 'timelines/resetTimelines',
                payload: noDelTimelines,
            });
        },
        *fetchEditorTimestamp({ payload }, { call, put, select }) {
            const { data } = yield call(DataServices.fetctTimestamp);
            let { outOfDate, serverTimestamp } = yield select(state => state.data);
            outOfDate = serverTimestamp !== data.timestamp;
            serverTimestamp = data.timestamp;
             // 传递信号
            yield put({
                type: 'save',
                payload: {
                    outOfDate,
                    serverTimestamp,
                },
            });
            if (outOfDate) {
                 // 获取数据
                // yield put({ type: 'pageJump/fetchPageJump' });
                // yield put({ type: 'pages/fetchPages' });
                yield put({ type: 'fetchData' });
                 // 数据获取成功，过后将过时标志，置为false
                yield put({
                    type: 'save',
                    payload: {
                        outOfDate: false,
                    },
                });
            } else {
                yield put({ type: 'pages/selectPage' });
            }
            // yield put({ type: 'fetchData' });
            // yield put({ type: 'pageJump/fetchPageJump' });
            // yield put({ type: 'pages/fetchPages' });
        },
        *fetchData({ payload: query }, { call, put }) {
            const { data } = yield call(DataServices.fetchData, query);
            // 传递信号
            yield put({
                type: 'save',
                payload: {
                    data,
                },
            });
            const pages = dataHelper.parsePagesFromServer(data.page_pages);
            const widgets = dataHelper.parseWidgetsFromServer(data.widgets);
            const timelines = dataHelper.parseTimelinesFromServer(data.timelines, widgets);
            yield put({ type: 'pageJump/updatePageJump', payload: data.page_jump });
            yield put({ type: 'pageTimelines/updatePageTimeline', payload: data.page_timelines });
            yield put({ type: 'pages/save', payload: pages });
            yield put({ type: 'widgets/save', payload: widgets });
            yield put({ type: 'timelines/resetTimelines', payload: timelines });
            yield put({ type: 'pages/selectPage', payload: pages[0] });
        },
    },
    subscriptions: {
        // 获取本地数据，拿去本地时间戳
        // 去服务端查询时间戳
        // 比对时间戳，不一致，则取服务端的数据
        // 如果一致，则说明本地数据已经是最新的，不用再获取数据
        setup({ dispatch, history }) {
            return history.listen(({ pathname, query }) => {
                if (pathname.indexOf('/editor') !== -1) {
                    // 暂未启用
                    persistHelper.ready(() => dispatch({ type: 'fetchEditorTimestamp', payload: query }), 'data');
                }
            });
        },
    },
};
